package cbr.resilienceManager.qmul.gemom;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 * the main search algorithm for the CBR
 *  
 * The static method used for the CBR
 * load the data from the database
 * save the data in the database
 * 
 * COPYRIGHT DISCLAIMER
 * Synopsis: All the source codes presented in this document are intellectual
 * properties of Queen Mary, University of London.
 * 
 * @year 2010
 * @author Peng Jiang, John Bigham, Jiayi Wu Jinfu Wang------------QMUL
 * @version 1.0 
 */

public class CbrSearch {

	// the current state, set by the autoFrame;
	private CbrData currentState;
	// the smallest value
	private float similarValue;
	// the ID in the database, which has the smallest values
	private int similarID;

	/**
	 * use for the data base coneection
	 * */
	// the driver of mysql
	private final static String driver = "com.mysql.jdbc.Driver";
	// the url of database
	private final static String url = "jdbc:mysql://127.0.0.1:3306/test";
	// the username
	private final static String user = "root";
	// the password
	private final static String password = "admin";

	public CbrSearch(CbrData cd) {

		currentState = cd;

		search();
	}

	/**
	 * according to the current state find the nearest value
	 * 
	 * @return float the similar value
	 * */
	private void search() {

		// connect to the data base

		try { 
			// load the driver
			Class.forName(driver); 

			// connect with database
			Connection conn = DriverManager.getConnection(url, user, password); 

			if(!conn.isClosed()) 
			{
				//System.out.println("Succeeded connecting to the Database!");	
			}
			// the case table the broker with gbid
			String table="statetable"+ currentState.getTableID();

			// get the number of states in the DB
			Statement statement = conn.createStatement();

			String sql="select count(*) from "+ table;

			ResultSet rs = statement.executeQuery(sql);

			int num=0;
			//get the number of 
			if(rs.next()){
				num=rs.getInt(1);
			}

			if(num!=0)
			{

				// loop the data
				sql= "select * from " + table;
				rs = statement.executeQuery(sql);

				float[] stateArray= new float[4];

				similarValue=90000000;

				while(rs.next()){

					stateArray[0]=rs.getFloat(2);
					stateArray[1]=rs.getFloat(3);
					stateArray[2]=rs.getFloat(4);
					stateArray[3]=rs.getFloat(5);
					float sv=similarValue(stateArray);
					// find the smallest value
					if(similarValue>sv)
					{
						similarValue=sv;
						similarID=rs.getInt(1);

					}
				}

				if(similarValue==0)
				{
					currentState.Nsate=false;

				}
				else{
					currentState.Nsate=true;
				}
				
				// get the solution based on the ID
				table="solutiontable"+ currentState.getTableID();
				sql = "select * from " + table + " where ID= "+ similarID;

				//System.out.println(sql);

				rs=statement.executeQuery(sql);
				String[] soluation= new String[4];
				// save the solution in the currentState
				if(rs.next()){

					soluation[0]=rs.getString(2);
					soluation[1]=rs.getString(3);
					soluation[2]=rs.getString(4);
					soluation[3]=rs.getString(5);
					currentState.setSoultion(soluation);
					currentState.setRisk(rs.getFloat(6));
				}
				else{
					currentState.Nsate=true;
				}
				
			}else
			{
				similarValue=-1;
				currentState.Nsate=true;
			}

		} catch(Exception e) { 

			e.printStackTrace(); 
		}

		System.out.println("similaryity =" + similarValue +"  ID="+ similarID);
		

	}

	/**
	 * the Similarity function
	 * @param float the previous state from DB
	 * */
	private float similarValue(float[] cd) {

		float v = 0;

		float[] state=currentState.getState();

		for (int i = 0; i < cd.length; i++) {

			v=v+Math.abs(state[i]-cd[i]);
		}

		return v;

	}

	/**
	 * @return the value of 
	 * */
	public float getValue(){

		return similarValue;
	}


	/**
	 * @return the CbrData with the nearest solution 
	 * */
	public CbrData getCbr()
	{
		return currentState;
	}




}
